package com.myk.game.gobangchess.ai.startzone;

public class StarZoneEngine {

    public static int[] starZoneEngine(int[][] inputBoard, int targetColor, int remainWhiteNum, int difficulty) {
        int[][] baseBoard = inputBoard;
        int color = targetColor;
        int numberOfZeros = sumMatrix(inputBoard, 0);
        int remainNum = 16 - sumMatrix(inputBoard, color);

        int checkingNum, maxGen, popSize;
        checkingNum = 500;
        maxGen = 1000;
        popSize = 200;
        if (difficulty == 1) {
            checkingNum = 20;
            maxGen = 100;
            popSize = 30;
        } else if (difficulty == 2) {
            checkingNum = 200;
            maxGen = 300;
            popSize = 100;
        } else if (difficulty == 3) {
            if (remainNum <= 2) {
                checkingNum = 200;
                maxGen = 500;
                popSize = 150;
            } else {
                checkingNum = 500;
                maxGen = 1000;
                popSize = 300;
            }
        }

        int[] settingIdx1 = {0, 0};
        int[] settingIdx2 = {0, 0};

        if (remainNum < 15) {
            GA_ALT gaAltInstance1 = new GA_ALT(); // Create an instance of the class
            GA_ALT.GA_ALT_Result result = gaAltInstance1.GA_ALT_1(baseBoard, color, numberOfZeros, remainNum, checkingNum, popSize, maxGen);



            color = -targetColor;
            baseBoard = inputBoard;
            numberOfZeros = sumMatrix(inputBoard, 0);
            remainNum = 16 - sumMatrix(inputBoard, color);

            GA_ALT gaAltInstance2 = new GA_ALT(); // Create an instance of the class
            GA_ALT.GA_ALT_Result resultAlt = gaAltInstance2.GA_ALT_1(baseBoard, color, numberOfZeros, remainNum, checkingNum, popSize, maxGen);


            remainNum = 16 - sumMatrix(inputBoard, targetColor);
            int[] colorSettingResult = ColorSetting.colorSetting(result.topFitnessesSorted, result.topGenesSorted,
                    resultAlt.topFitnessesSorted, resultAlt.topGenesSorted, inputBoard, remainNum, remainWhiteNum, targetColor);

            settingIdx1[0] = colorSettingResult[0];
            settingIdx1[1] = colorSettingResult[1];
            settingIdx2[0] = colorSettingResult[2];
            settingIdx2[1] = colorSettingResult[3];
            if (remainNum == 10) {
                boolean copying = true;
                for (int i = 0; i < 9; i++) {
                    for (int j = 0; j < 9; j++) {
                        if (baseBoard[i][j] == -targetColor && baseBoard[8 - i][8 - j] != targetColor) {
                            copying = false;
                        }
                    }
                }
                if (copying && baseBoard[9 - settingIdx1[0]][9 - settingIdx1[1]] == 0) {
                    settingIdx2[0] = 10 - settingIdx1[0];
                    settingIdx2[1] = 10 - settingIdx1[1];
                }
            }
        } else {

            int[][] baseboard = baseBoard;
            boolean cond_1_m = (baseboard[3][0] == targetColor) || (baseboard[4][0] == targetColor);
            boolean cond_1_o = (baseboard[3][0] == -targetColor) || (baseboard[4][0] == -targetColor);
            boolean cond_9_m = (baseboard[4][8] == targetColor) || (baseboard[5][8] == targetColor);
            boolean cond_9_o = (baseboard[4][8] == -targetColor) || (baseboard[5][8] == -targetColor);
            boolean cond_1_m_alt = (baseboard[0][3] == targetColor) || (baseboard[0][4] == targetColor);
            boolean cond_1_o_alt = (baseboard[0][3] == -targetColor) || (baseboard[0][4] == -targetColor);
            boolean cond_9_m_alt = (baseboard[8][4] == targetColor) || (baseboard[8][5] == targetColor);
            boolean cond_9_o_alt = (baseboard[8][4] == -targetColor) || (baseboard[8][5] == -targetColor);
            
            if (!cond_1_m && cond_9_o) {
                if (baseboard[3][0] == 0) {
                    settingIdx1 = new int[]{4, 1};
                    if (baseboard[4][0] == 0) {
                        settingIdx2 = new int[]{5, 1};
                    }
                } else if (baseboard[4][0] == 0) {
                    settingIdx1 = new int[]{5, 1};
                } else if (baseboard[4][8] == 0) {
                    settingIdx1 = new int[]{5, 9};
                } else if (baseboard[5][8] == 0) {
                    settingIdx1 = new int[]{6, 9};
                }
            } else if (!cond_9_m && cond_1_o) {
                if (baseboard[5][8] == 0) {
                    settingIdx1 = new int[]{6, 9};
                    if (baseboard[4][8] == 0) {
                        settingIdx2 = new int[]{5, 9};
                    }
                } else if (baseboard[4][8] == 0) {
                    settingIdx1 = new int[]{5, 9};
                } else if (baseboard[3][0] == 0) {
                    settingIdx1 = new int[]{4, 1};
                } else if (baseboard[4][0] == 0) {
                    settingIdx1 = new int[]{5, 1};
                }
            } else if (!cond_1_m_alt && cond_9_o_alt) {
                if (baseboard[0][3] == 0) {
                    settingIdx1 = new int[]{1, 4};
                    if (baseboard[0][4] == 0) {
                        settingIdx2 = new int[]{1, 5};
                    }
                } else if (baseboard[0][4] == 0) {
                    settingIdx1 = new int[]{1, 5};
                } else if (baseboard[8][4] == 0) {
                    settingIdx1 = new int[]{9, 5};
                } else if (baseboard[8][5] == 0) {
                    settingIdx1 = new int[]{9, 6};
                }
            } else if (!cond_9_m_alt && cond_1_o_alt) {
                if (baseboard[8][5] == 0) {
                    settingIdx1 = new int[]{9, 6};
                    if (baseboard[8][4] == 0) {
                        settingIdx2 = new int[]{9, 5};
                    }
                } else if (baseboard[8][4] == 0) {
                    settingIdx1 = new int[]{9, 5};
                } else if (baseboard[0][3] == 0) {
                    settingIdx1 = new int[]{1, 4};
                } else if (baseboard[0][4] == 0) {
                    settingIdx1 = new int[]{1, 5};
                }
            } else if (!cond_1_m && !cond_9_m) {
                if (baseboard[3][0] == 0) {
                    settingIdx1 = new int[]{4, 1};
                    if (baseboard[4][0] == 0) {
                        settingIdx2 = new int[]{5, 1};
                    }
                } else if (baseboard[4][0] == 0) {
                    settingIdx1 = new int[]{5, 1};
                } else if (baseboard[4][8] == 0) {
                    settingIdx1 = new int[]{5, 9};
                } else if (baseboard[5][8] == 0) {
                    settingIdx1 = new int[]{6, 9};
                }
            } else if (!cond_1_m_alt && !cond_9_m_alt) {
                if (baseboard[0][3] == 0) {
                    settingIdx1 = new int[]{1, 4};
                    if (baseboard[0][4] == 0) {
                        settingIdx2 = new int[]{1, 5};
                    }
                } else if (baseboard[0][4] == 0) {
                    settingIdx1 = new int[]{1, 5};
                } else if (baseboard[8][4] == 0) {
                    settingIdx1 = new int[]{9, 5};
                } else if (baseboard[8][5] == 0) {
                    settingIdx1 = new int[]{9, 6};
                }
            }
            
        }
        return new int[]{settingIdx1[0], settingIdx1[1], settingIdx2[0], settingIdx2[1]};
    }

    private static int sumMatrix(int[][] matrix, int target) {
        int sum = 0;
        for (int[] row : matrix) {
            for (int value : row) {
                if (value == target) {
                    sum++;
                }
            }
        }
        return sum;
    }


    public static void main(String[] args) {
        int[][] inputBoard = {
            {3, 3, 3, 1, 2, 3, 3, 3, 3},
            {3, 3,-1, 0, 0, 0, 0, 0, 3},
            {3, 0, 0, 0, 0, 0, 0, 0, 3},
            {-1, 0, 0,-1, 0,-1, 0,-1, 3},
            {0, 0, 0, 0, 2, 0, 0, 0, 0},
            {3, 1, 0, 1, 0, 1, 0, 0, 1},
            {3, 0, 0, 0, 0, 0, 0, 0, 3},
            {3, 0,-1, 0, 0, 0, 1, 3, 3},
            {3, 3, 3, 3, 0,-1, 3, 3, 3}
        };
        int targetColor = 1;
        int remainWhiteNum = 5;
        int difficulty = 3;

        int[] result = starZoneEngine(inputBoard, targetColor, remainWhiteNum, difficulty);

        System.out.println("Setting Index 1: " + result[0] + ", " + result[1]);
        System.out.println("Setting Index 2: " + result[2] + ", " + result[3]);
    }
}

